//! Map 抽象层演示
//! 
//! 展示如何使用统一的 Map 接口实现 Java 风格的面向接口编程
//! 降低替换成本，提高代码的可维护性和扩展性

use std::collections::HashMap;
use fxhash::FxHashMap;
use ahash::AHashMap;
use std::hash::Hash;

/// 通用 Map trait，抽象底层实现
pub trait MapTrait<K, V> 
where 
    K: Eq + Hash + Clone,
    V: Clone,
{
    /// 插入键值对，返回旧值（如果存在）
    fn insert(&mut self, key: K, value: V) -> Option<V>;
    
    /// 获取值的引用
    fn get(&self, key: &K) -> Option<&V>;
    
    /// 删除键值对，返回旧值（如果存在）
    fn remove(&mut self, key: &K) -> Option<V>;
    
    /// 检查是否包含指定键
    fn contains_key(&self, key: &K) -> bool;
    
    /// 获取元素数量
    fn len(&self) -> usize;
    
    /// 检查是否为空
    fn is_empty(&self) -> bool {
        self.len() == 0
    }
    
    /// 获取哈希算法名称（用于调试）
    fn hasher_name(&self) -> &'static str;
}

/// 为 HashMap 实现 MapTrait
impl<K, V> MapTrait<K, V> for HashMap<K, V>
where
    K: Eq + Hash + Clone,
    V: Clone,
{
    fn insert(&mut self, key: K, value: V) -> Option<V> {
        HashMap::insert(self, key, value)
    }
    
    fn get(&self, key: &K) -> Option<&V> {
        HashMap::get(self, key)
    }
    
    fn remove(&mut self, key: &K) -> Option<V> {
        HashMap::remove(self, key)
    }
    
    fn contains_key(&self, key: &K) -> bool {
        HashMap::contains_key(self, key)
    }
    
    fn len(&self) -> usize {
        HashMap::len(self)
    }
    
    fn hasher_name(&self) -> &'static str {
        "SipHash (StandardLibrary)"
    }
}

/// 为 FxHashMap 实现 MapTrait
impl<K, V> MapTrait<K, V> for FxHashMap<K, V>
where
    K: Eq + Hash + Clone,
    V: Clone,
{
    fn insert(&mut self, key: K, value: V) -> Option<V> {
        FxHashMap::insert(self, key, value)
    }
    
    fn get(&self, key: &K) -> Option<&V> {
        FxHashMap::get(self, key)
    }
    
    fn remove(&mut self, key: &K) -> Option<V> {
        FxHashMap::remove(self, key)
    }
    
    fn contains_key(&self, key: &K) -> bool {
        FxHashMap::contains_key(self, key)
    }
    
    fn len(&self) -> usize {
        FxHashMap::len(self)
    }
    
    fn hasher_name(&self) -> &'static str {
        "FxHash (High-Performance)"
    }
}

/// 为 AHashMap 实现 MapTrait
impl<K, V> MapTrait<K, V> for AHashMap<K, V>
where
    K: Eq + Hash + Clone,
    V: Clone,
{
    fn insert(&mut self, key: K, value: V) -> Option<V> {
        AHashMap::insert(self, key, value)
    }
    
    fn get(&self, key: &K) -> Option<&V> {
        AHashMap::get(self, key)
    }
    
    fn remove(&mut self, key: &K) -> Option<V> {
        AHashMap::remove(self, key)
    }
    
    fn contains_key(&self, key: &K) -> bool {
        AHashMap::contains_key(self, key)
    }
    
    fn len(&self) -> usize {
        AHashMap::len(self)
    }
    
    fn hasher_name(&self) -> &'static str {
        "AHash (Modern High-Performance)"
    }
}

/// Map 类型枚举，用于运行时选择
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MapType {
    /// 标准库 HashMap (SipHash)
    StandardHashMap,
    /// FxHashMap (高性能)
    FxHashMap,
    /// AHashMap (现代高性能)
    AHashMap,
}

/// Map 工厂，类似 Java 的工厂模式
pub struct MapFactory;

impl MapFactory {
    /// 创建指定类型的 Map
    pub fn create_map<K, V>(map_type: MapType) -> Box<dyn MapTrait<K, V>>
    where
        K: Eq + Hash + Clone + 'static,
        V: Clone + 'static,
    {
        match map_type {
            MapType::StandardHashMap => Box::new(HashMap::<K, V>::new()),
            MapType::FxHashMap => Box::new(FxHashMap::<K, V>::default()),
            MapType::AHashMap => Box::new(AHashMap::<K, V>::new()),
        }
    }
}

/// 演示业务服务类，模拟 Java 风格的编程
pub struct DataService {
    cache: Box<dyn MapTrait<String, String>>,
    config: Box<dyn MapTrait<String, String>>,
}

impl DataService {
    pub fn new(cache_type: MapType, config_type: MapType) -> Self {
        Self {
            cache: MapFactory::create_map(cache_type),
            config: MapFactory::create_map(config_type),
        }
    }
    
    pub fn set_cache(&mut self, key: &str, value: &str) {
        self.cache.insert(key.to_string(), value.to_string());
    }
    
    pub fn get_cache(&self, key: &str) -> Option<&String> {
        self.cache.get(&key.to_string())
    }
    
    pub fn set_config(&mut self, key: &str, value: &str) {
        self.config.insert(key.to_string(), value.to_string());
    }
    
    pub fn get_config(&self, key: &str) -> Option<&String> {
        self.config.get(&key.to_string())
    }
    
    pub fn cache_info(&self) -> String {
        format!("Cache: {} ({} items)", 
               self.cache.hasher_name(), 
               self.cache.len())
    }
    
    pub fn config_info(&self) -> String {
        format!("Config: {} ({} items)", 
               self.config.hasher_name(), 
               self.config.len())
    }
}

fn main() {
    println!("🎯 Rust Map 抽象层演示 - Java 风格接口编程");
    println!("{}", "=".repeat(60));
    
    // 1. 基本 Map 抽象使用
    println!("\n📋 1. 基本 Map 抽象使用");
    let mut maps: Vec<Box<dyn MapTrait<String, i32>>> = vec![
        MapFactory::create_map(MapType::StandardHashMap),
        MapFactory::create_map(MapType::FxHashMap),
        MapFactory::create_map(MapType::AHashMap),
    ];
    
    for (i, map) in maps.iter_mut().enumerate() {
        println!("  测试 Map {}: {}", i + 1, map.hasher_name());
        map.insert(format!("key_{}", i), i as i32 * 100);
        println!("    插入: key_{} = {}", i, i * 100);
        println!("    查询: {:?}", map.get(&format!("key_{}", i)));
        println!("    大小: {}", map.len());
    }
    
    // 2. 工厂模式的优势
    println!("\n🏭 2. 工厂模式的优势");
    
    // 根据环境选择不同的实现
    fn create_for_environment(is_production: bool) -> Box<dyn MapTrait<String, String>> {
        if is_production {
            // 生产环境使用高性能实现
            MapFactory::create_map(MapType::FxHashMap)
        } else {
            // 开发环境使用安全实现
            MapFactory::create_map(MapType::StandardHashMap)
        }
    }
    
    let prod_map = create_for_environment(true);
    let dev_map = create_for_environment(false);
    
    println!("  生产环境 Map: {}", prod_map.hasher_name());
    println!("  开发环境 Map: {}", dev_map.hasher_name());
    
    // 3. Java 风格的业务服务
    println!("\n☕ 3. Java 风格的业务服务");
    
    let mut high_perf_service = DataService::new(MapType::FxHashMap, MapType::StandardHashMap);
    let mut balanced_service = DataService::new(MapType::AHashMap, MapType::AHashMap);
    
    // 使用统一的接口
    high_perf_service.set_cache("user:1", "Alice");
    high_perf_service.set_config("timeout", "30");
    
    balanced_service.set_cache("user:2", "Bob");
    balanced_service.set_config("retries", "3");
    
    println!("  高性能服务:");
    println!("    {}", high_perf_service.cache_info());
    println!("    {}", high_perf_service.config_info());
    println!("    缓存数据: {:?}", high_perf_service.get_cache("user:1"));
    
    println!("  平衡服务:");
    println!("    {}", balanced_service.cache_info());
    println!("    {}", balanced_service.config_info());
    println!("    缓存数据: {:?}", balanced_service.get_cache("user:2"));
    
    // 4. 性能对比演示
    println!("\n⚡ 4. 性能对比演示");
    
    const TEST_SIZE: usize = 100_000;
    
    // 测试不同算法的性能
    let map_types = [
        ("SipHash", MapType::StandardHashMap),
        ("FxHash", MapType::FxHashMap),
        ("AHash", MapType::AHashMap),
    ];
    
    for (name, map_type) in &map_types {
        let mut map = MapFactory::create_map::<String, i32>(*map_type);
        
        let start = std::time::Instant::now();
        for i in 0..TEST_SIZE {
            map.insert(format!("key_{}", i), i as i32);
        }
        let insert_time = start.elapsed();
        
        let start = std::time::Instant::now();
        for i in 0..TEST_SIZE {
            let _ = map.get(&format!("key_{}", i));
        }
        let search_time = start.elapsed();
        
        println!("  {} ({}):", name, map.hasher_name());
        println!("    插入 {} 条: {:?}", TEST_SIZE, insert_time);
        println!("    查找 {} 条: {:?}", TEST_SIZE, search_time);
        println!("    插入速率: {:.0} ops/秒", TEST_SIZE as f64 / insert_time.as_secs_f64());
        println!("    查找速率: {:.0} ops/秒", TEST_SIZE as f64 / search_time.as_secs_f64());
    }
    
    println!("\n🎉 总结：Redis-rs2 现在支持 Java 风格的接口编程！");
    println!("✅ 优势：");
    println!("  - 统一的 Map 接口抽象");
    println!("  - 工厂模式降低耦合");
    println!("  - 运行时可配置性");
    println!("  - 最小化替换成本");
    println!("  - 类型安全的多态性");
}